#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

const int PORT = 23816;
const int BUFLEN = 0x100;

int main()
{
	//create listen socket
	int ls = socket(AF_INET, SOCK_STREAM, 0);
	if(ls == -1){
		perror("Can't create socket");
		exit(EXIT_FAILURE);
	}

	//bind to any adress on port 23816
	struct sockaddr_in bind_adress = {
		AF_INET,
		htons(PORT),
		{INADDR_ANY},
	};
	int err = bind(ls, (struct sockaddr *)&bind_adress, sizeof(bind_adress));
	if(err == -1){
		perror("Can't bind socket");
		exit(EXIT_FAILURE);
	}

	//make socket passive(listen)
	err = listen(ls, 1);
	if(err == -1){
		perror("listen failed");
		exit(EXIT_FAILURE);		
	}

	//wait for connection from client
	int cs = accept(ls, NULL, NULL);
	if(cs == -1){
		perror("accept failed");
		exit(EXIT_FAILURE);
	}

	//I can close listening socket
	//I don't need it anymore
	close(ls);

	//read bytes from connected socket and print them to console
	ssize_t readed = 0;
	char buf[BUFLEN] = {0};
	do{
		//try to read something
		readed = recv(cs, buf, sizeof(buf), 0);

		//I are able to read something from connection, print it to console
		if(readed > 0){
			fwrite(buf, 1, readed, stdout);
			continue;
		}
		
		//peer close connection, quit loop
		if(readed == 0)
			break;

		//non fatal event interrupt recv syscall, continue to read
		if(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
			continue;

		//error occurred, print and exit
		if(readed < 0){
			perror("Error during recv");
			exit(EXIT_FAILURE);
		}
	}while(1);

	
	//close socket
	close(cs);

	//print eol, just to beautify output
	putc('\n', stdout);
}
